package cn.px.service.aliyun.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import cn.px.common.exception.BusinessException;
import cn.px.common.util.BeanUtils;
import cn.px.common.util.MapUtils;
import cn.px.service.aliyun.constant.ActionConstant;
import cn.px.service.aliyun.constant.SendSmsPramConstant;
import cn.px.service.aliyun.constant.SignConstant;
import cn.px.service.aliyun.constant.TemplateConstant;
import cn.px.service.aliyun.service.MessageService;
import cn.px.service.request.bean.BaseRequest;
import cn.px.service.request.dto.RequestDTO;
import cn.px.service.request.enums.RequestMethodEnum;
import cn.px.service.request.enums.SysRequestLogTypeEnum;
import cn.px.service.request.model.ResponseData;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;

/**
 * @Description 阿里云短信服务
 * @author 品讯科技
 * @date 2024-08
 * @Version Copyright (c) 2019,北京乾元坤和科技有限公司 All rights reserved.
 */
@Slf4j
@Service
@AllArgsConstructor
public class MessageServiceImpl implements MessageService {
    /**
     * 客户端
     */
    private final IAcsClient iAcsClient;


    private final static String DOMAIN = "dysmsapi.aliyuncs.com";
    private final static String VERSION = "2017-05-25";

    private MethodType getMethod(RequestMethodEnum method) {
        if (RequestMethodEnum.POST.equals(method)) {
            return MethodType.POST;
        }
        throw new BusinessException("未处理请求类型");
    }

    @SneakyThrows
    public ResponseData request(SysRequestLogTypeEnum sysRequestLogTypeEnum, RequestDTO requestModel, BiConsumer<CommonRequest, RequestDTO> consumer) {
        return BeanUtils.getBean(BaseRequest.class).request(sysRequestLogTypeEnum, requestModel, (r) -> {
            CommonRequest request = new CommonRequest();
            request.setDomain(DOMAIN);
            // 必填
            request.setVersion(VERSION);
            request.setAction(requestModel.getUrl());
            request.setMethod(this.getMethod(requestModel.getMethod()));
            consumer.accept(request, requestModel);
            try {
                CommonResponse response = iAcsClient.getCommonResponse(request);
                return this.createResponseData(response);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        });
    }

    @Override
    @SneakyThrows
    public ResponseData sendSms(String phoneNumbers, String signName, String templateCode, Map<String, String> templateParam) {
        Map<String, String> params = MapUtils.newHashMap(4);
        params.put(SendSmsPramConstant.PHONE_NUMBERS, phoneNumbers);
        params.put(SendSmsPramConstant.SIGN_NAME, signName);
        params.put(SendSmsPramConstant.TEMPLATE_CODE, templateCode);
        params.put(SendSmsPramConstant.TEMPLATE_PARAM, JSON.toJSONString(templateParam));
        SysRequestLogTypeEnum sysRequestLogTypeEnum = SysRequestLogTypeEnum.ALIYUN_SMS;
        return this.request(sysRequestLogTypeEnum,
                new RequestDTO().setParams(params).setMethod(RequestMethodEnum.POST).setUrl(ActionConstant.SEND_SMS),
                (r, p) -> p.getParams().forEach(r::putQueryParameter));
    }

    /**
     * 自定义返回类型
     *
     * @param r :
     * @return :
     */
    public ResponseData createResponseData(Object r) {
        CommonResponse response = (CommonResponse) r;
        if (ObjectUtil.isNull(response.getData())) {
            return null;
        }
        ResponseData responseData = new ResponseData();
        JSONObject jsonObject = JSONUtil.parseObj(response.getData());
        responseData.setCode(jsonObject.getStr("Code"));
        responseData.setMessage(jsonObject.getStr("Message"));
        responseData.setRequestId(jsonObject.getStr("RequestId"));
        responseData.setResult(r);
        return responseData;
    }

    @Override
    @SneakyThrows
    public ResponseData sendValidateCode(String phoneNumbers, String code) {
        Map<String, String> templateParam = new HashMap<>(1);
        templateParam.put("code", code);

        return sendSms(phoneNumbers, SignConstant.ASSET_MANAGE_SYSTEM, TemplateConstant.VALIDATION_CODE, templateParam);
    }
}
